import 'dart:async';
import 'dart:io';
import 'package:bot_toast/bot_toast.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:intl/intl.dart';

import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:logger/logger.dart';
import 'package:wechat_assets_picker/wechat_assets_picker.dart';

import '../base/base_theme_data.dart';
import '../base/compat_console_output.dart';
import '../base/logger_filter.dart';
import '../config/const_config.dart';
import '../config/route_config.dart';
import '../widget/custom_loading.dart';
import '../widget/custom_toast_widget.dart';
import 'local_manage.dart';


GlobalKey<NavigatorState> globalKey = GlobalKey<NavigatorState>();

enum LoadType {
  LOAD,
  LOAD_REFRESH,
  LOAD_MORE,
}

Logger logger =
    Logger(filter: LoggerFilter(), printer: PrettyPrinter(methodCount: 0));

Logger loggerJson = Logger(
    filter: LoggerFilter(),
    output: CompatConsoleOutput(),
    printer: PrettyPrinter(methodCount: 0));

double screenWidth() => ScreenUtil().screenWidth;

double screenHeight() => ScreenUtil().screenHeight;

double screenUtilW(double width) => ScreenUtil().setWidth(width);

double screenUtilH(double height) => ScreenUtil().setHeight(height);

double screenUtilF(int fontSize) => ScreenUtil().setSp(fontSize);

double screenUtilR(double radius) => ScreenUtil().radius(radius);

BuildContext getCurContext() => globalKey.currentContext!;

showKeyboard(_focusNode) {
  SystemChannels.textInput.invokeMethod('TextInput.show');
}

hideKeyboard() {
  SystemChannels.textInput.invokeMethod('TextInput.hide');
}

hideKeyboardFocus() {
  // 移除焦点可能会导致布局重新渲染
  FocusManager.instance.primaryFocus?.unfocus();
  hideKeyboard();
}

bool saveToken() {
  String? tokenStr = LocalManage.getSp().getString(ConstConfig.token);
  if (tokenStr == null || tokenStr.isEmpty) {
    return false;
  }
  return true;
}

/// 获取Token信息
String? getToken() => LocalManage.getSp().getString(ConstConfig.token);

/// 函数防抖
/// [func]: 要执行的方法
/// [delay]: 要迟延的时长
///
Function debounceCommon(
  Function? func, [
  Duration delay = const Duration(milliseconds: 500),
]) {
  Timer? timer;
  Function target = () {
    if (timer?.isActive ?? false) {
      timer?.cancel();
    }
    timer = Timer(delay, () {
      func?.call();
    });
  };
  return target;
}

Function(T t) debounceOne<T>(
  Function(T t)? func, [
  Duration delay = const Duration(milliseconds: 1000),
]) {
  Timer? timer;
  Function(T t) target = (T t) {
    if (timer?.isActive ?? false) {
      timer?.cancel();
    }
    timer = Timer(delay, () {
      func?.call(t);
    });
  };
  return target;
}

//
Function(T t, D d) debounceTwo<T, D>(
  Function(T t, D d)? func, [
  Duration delay = const Duration(milliseconds: 1000),
]) {
  Timer? timer;
  Function(T t, D d) target = (T t, D d) {
    if (timer?.isActive ?? false) {
      timer?.cancel();
    }
    timer = Timer(delay, () {
      func?.call(t, d);
    });
  };
  return target;
}

//
// //普通点击
Widget debounceClickBtn({
  Widget? child,
  Function? onTap,
  Duration delay = const Duration(milliseconds: 300),
}) {
  Function fun = debounceCommon(onTap, delay);
  return GestureDetector(
    behavior: HitTestBehavior.opaque,
    onTap: () {
      fun.call();
    },
    child: child,
  );
}

/// 函数节流
/// [func]: 要执行的方法
/// [delay]: 指定时长内过滤
///
Function throttle(
  Function? func, [
  int delay = 1000,
]) {
  int prev = 0;
  Function target = () {
    int now = DateTime.now().millisecondsSinceEpoch;
    if (now - prev >= delay) {
      func?.call();
      prev = DateTime.now().millisecondsSinceEpoch;
    }
  };
  return target;
}

Function(T t) throttleOne<T>(
  Function(T t)? func, [
  int delay = 1000,
]) {
  int prev = 0;
  Function(T t) target = (t) {
    int now = DateTime.now().millisecondsSinceEpoch;
    if (now - prev >= delay) {
      func?.call(t);
      prev = DateTime.now().millisecondsSinceEpoch;
    }
  };
  return target;
}

//普通点击
Widget throttleClickBtn({Widget? child, Function? onTap, int delay = 1000}) {
  Function fun = throttle(onTap, delay);
  return GestureDetector(
    behavior: HitTestBehavior.opaque,
    onTap: () {
      fun.call();
    },
    child: child,
  );
}

//水波纹点击
Widget throttleInkWellBtn(
    {Widget? child,
    Function(TapDownDetails details)? onTapDown,
    Function()? onTap,
    Color color = Colors.transparent,
    Color? splashColor,
    Color? highlightColor,
    BorderRadius? inkWellBorderRadius,
    BorderRadius? borderRadius,
    int delay = 1000}) {
  Function fun = throttle(onTap, delay);
  Function(TapDownDetails e) fun1 =
      throttleOne<TapDownDetails>(onTapDown, delay);
  return Material(
    color: color,
    borderRadius: borderRadius,
    child: InkWell(
      splashColor: splashColor ?? Colors.black.withOpacity(0.12),
      highlightColor: highlightColor ?? Colors.black.withOpacity(0.04),
      borderRadius: inkWellBorderRadius,
      onTapDown: onTap != null
          ? (e) {
              fun1.call(e);
            }
          : null,
      onTap: onTap != null
          ? () {
              fun.call();
            }
          : null,
      child: child,
    ),
  );
}


/// 对象非空
isNotEmptyOrNull(dynamic data) {
  if (data == null) {
    return false;
  } else if (data is String) {
    return data.isNotEmpty;
  } else if (data is List) {
    return data.isNotEmpty;
  } else if (data is Map) {
    return data.isNotEmpty;
  }
  return true;
}

/// 对象为空
isEmptyOrNull(dynamic data) {
  if (data == null) {
    return true;
  } else if (data is String) {
    return data.isEmpty;
  } else if (data is List) {
    return data.isEmpty;
  } else if (data is Map) {
    return data.isEmpty;
  }
  return false;
}

// 防止多次执行
var _logoutFun = throttle(() async {
  await LocalManage.logout();
});

/// 退出登录
logout() async {
  _logoutFun.call();
}


/// 全局toast
showToast(String text) {
  BotToast.showText(
      text: text, align: const Alignment(0, 0.4), contentColor: Colors.black);
}

showToastSuccess(String? text) {
  _showToast(text, ToastState.success);
}

showToastFail(String? text) {
  _showToast(text, ToastState.fail);
}

showToastWarning(String? text) {
  _showToast(text, ToastState.warning);
}

_showToast(String? text, ToastState? state) {
  BotToast.showCustomLoading(
      clickClose: true,
      allowClick: true,
      crossPage: true,
      duration: const Duration(seconds: 2),
      backgroundColor: Colors.transparent,
      toastBuilder: (cancelFunc) {
        return CustomToastWidget(
            cancelFunc: cancelFunc, state: state, contentText: text);
      });
}

/// 全局loading
CancelFunc? loading;

showLoading() {
  loading?.call();
  // loading = BotToast.showLoading(backgroundColor: Colors.transparent);
  loading = BotToast.showCustomLoading(
      backgroundColor: Colors.transparent,
      toastBuilder: (void Function() cancelFunc) {
        return const CustomLoading();
      }
  );
}

hideLoading() {
  loading?.call();
}


/// 预览网络图片
Future? previewNetworkImages({
  List<String>? urls,
  int selected = 0,
}) {
  return Get.toNamed(RouteConfig.previewImage,
      arguments: {"urls": urls, "selected": selected});
}

/// 预览图片
Future<List<AssetEntity>?> previewPhotos<T>({
  List<AssetEntity>? previewAssets,
}) {
  return AssetPickerViewer.pushToViewer(
    getCurContext(),
    previewAssets: previewAssets ?? [],
    themeData: getTheme(),
  );
}

///是否打印日志
const bool printLog =
    String.fromEnvironment('htm.env', defaultValue: "dev") != "pro";


/// 当前环境
/// flutter build apk --debug --dart-define=htm.env=dev
const bool isDebug = kDebugMode ||
    String.fromEnvironment('htm.env', defaultValue: "dev") == "dev";


Future<String?> getDeviceToken() async {
  MethodChannel channel = const MethodChannel('com.zsts.http.proxy');
  Future<String?> deviceToken = channel.invokeMethod('getDeviceToken');
  return deviceToken;
}

// 修改时间格式
String changeDateTimeFormateWithDataStr(String oldDateStr,
    {String newFormat = 'yyyy-MM-dd'}) {
  if (oldDateStr.isEmpty) {
    return '';
  }
  String strTime = oldDateStr;
  DateTime oldTime = DateFormat("yyyy-MM-dd HH:mm:ss").parse(strTime);
  String newTime = DateFormat(newFormat).format(oldTime);
  return newTime;
}

bool hasMatch(String? value, String pattern) {
  return (value == null) ? false : RegExp(pattern).hasMatch(value);
}
